home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / MNetsrc.hqx / Mac TCP_IP Source v.33 / mac_at.c < prev    next >
Text File  |  1989-03-21  |  13KB  |  593 lines

  1. /*
  2.  * This code is Copyright (C) 1987, by Mikel Matthews, N9DVG, All Rights Reserved.
  3.  * Permission granted for non-commercial copying and use, provided
  4.  * this notice is retained.
  5.  */
  6.  
  7.  
  8. #include <stdio.h>
  9. #include "global.h"
  10. #include "mbuf.h"
  11. #include "iface.h"
  12. #include "timer.h"
  13. #include "ip.h"
  14. #include "arp.h"
  15. #include <MacTypes.h>
  16. #include <Appletalk.h>
  17. #include "mac_AT.h"
  18. #include "trace.h"
  19.  
  20. struct at at[AT_MAX];        /* Per-controller info */
  21.  
  22. unsigned char appletalk_bdcst[] = 0xff;    /* all devices will read this address */
  23.  
  24. #ifdef    TRACE
  25. #include "trace.h"
  26. int at_dump();
  27. extern trace;
  28. #endif    TRACE
  29. unsigned    nat = 0;        /* Number of apple talk devices */
  30.     
  31. /* Initialize interface */
  32. at_init(interface,bufsize)
  33. struct interface *interface;
  34. unsigned bufsize;    /* Maximum size of receive queue in PACKETS */
  35. {
  36.     register struct at *atp;
  37.     int16 dev;
  38.     char *malloc();
  39.     int err;
  40.     ABRecPtr abrrdptr;
  41.     ABRecPtr abrwrptr;
  42.     unsigned int node, net;        /* vars to hold my node id and net id */
  43.     
  44. #ifdef DEBUG
  45.     printf("at_init called\n");
  46. #endif
  47.     dev = interface->dev;
  48.     /* 
  49.      * this check is only here because I sometimes get a little parinoid
  50.      */
  51.      
  52.     if ( dev >= nat )    
  53.     {
  54.         printf("at_init: problem with dev entry.  Number is  %d, max = %d.\n", dev,nat);
  55.         return(-1);
  56.     }
  57.     atp = &at[dev];
  58.     atp->rcvmax = bufsize;
  59.     /*
  60.      * see if the device is available for use with AppleTalk
  61.      */
  62.     err = MPPOpen();
  63.     if ( err != noErr )
  64.     {
  65.         printf("at_init: AppleTalk is not available on device. Error %d\n", err);
  66.         return(-1);
  67.     }
  68.  
  69.     /*
  70.      * See if we can put our protocol type in and have the default handler use it
  71.      */
  72.     err = LAPOpenProtocol(atp->ProtoType, NULL);
  73.     if ( err != noErr)
  74.     {
  75.         /*
  76.          * In case we bombed out last time, try and remove the protocol type and try again
  77.          */
  78.         if ( LAPCloseProtocol(atp->ProtoType) != 0 )
  79.         {
  80.  
  81.             printf("at_init: Could not initialize AppleTalk with protocol type %d, error %d.\n",
  82.                  atp->ProtoType, err);
  83.             return(-1);
  84.         }
  85.         err = LAPOpenProtocol(atp->ProtoType, NULL);
  86.         if ( err != noErr)
  87.         {
  88.             printf("at_init: Could not initialize AppleTalk with protocol type %d, error %d.\n",
  89.                  atp->ProtoType, err);
  90.             return(-1);
  91.         }
  92.     }
  93.     /*
  94.      * Since everything is alright, lets allocate an ABusRecord
  95.      */
  96.     
  97.     atp->rdATptr = (ABRecHandle) NewHandle(lapSize);
  98.     if ( atp->rdATptr == NULL)
  99.     {
  100.         printf("at_init: Could not allocate handle for AppleBus (0).\n");
  101.         (void)LAPCloseProtocol(atp->ProtoType);
  102.         return(-1);
  103.     }
  104.     atp->wrATptr = (ABRecHandle) NewHandle(lapSize);
  105.     
  106.     if ( atp->wrATptr == NULL)
  107.     {
  108.         printf("at_init: Could not allocate handle for AppleBus (1).\n");
  109.         DisposHandle(atp->rdATptr);
  110.         (void)LAPCloseProtocol(atp->ProtoType);
  111.         return(-1);
  112.     }
  113.     /*
  114.      * now that everything is going well, let's issue an async read on the protocol
  115.      */
  116.     HLock(atp->rdATptr);
  117.     HLock(atp->wrATptr);
  118.     abrrdptr = *atp->rdATptr;
  119.     abrwrptr = *atp->wrATptr;
  120.     
  121.     abrwrptr->lapProto.lapAddress.lapProtType = atp->ProtoType;
  122.     if ( at_startread(atp, abrrdptr) != 0 )
  123.     {
  124.         printf("at_init: Could not perform read on AppleTalk network.  Closing down device.\n");
  125.         return(-1);
  126.     }
  127.     /*
  128.      * This subroutine will return a unique node address
  129.      */
  130.     if ( GetNodeAddress( &node, &net) != 0)
  131.     {
  132.         printf("at_init: Could not get my own node address.  Something is wrong!!\n");
  133.         return(-1);
  134.     }
  135.     /*
  136.      * set up the hardware address in the interface struct
  137.      */
  138.     if ( interface->hwaddr == NULLCHAR )
  139.     {
  140.         if ( (interface -> hwaddr = malloc(4)) == NULLCHAR)
  141.         {
  142.             printf("at_init: Could not allocate memory for hardware address.\n");
  143.             return(-1);
  144.         }
  145.     }
  146.         
  147.     *interface->hwaddr = (unsigned char) node;
  148.      printf("My AppleTalk node number is %d\n", node);     
  149.     return(0);
  150. }
  151.  
  152. /* Send an IP datagram on AppleTalk */
  153. at_send(bp,interface,gateway,precedence,delay,throughput,reliability)
  154. struct mbuf *bp;        /* Buffer to send */
  155. struct interface *interface;    /* Pointer to interface control block */
  156. int32 gateway;            /* IP address of next hop */
  157. char precedence;
  158. char delay;
  159. char throughput;
  160. char reliability;
  161. {
  162.     char *egate,*res_arp();
  163.     egate = res_arp(interface,ARP_APPLETALK,gateway,bp);
  164.     if(egate != NULLCHAR)
  165.     {
  166.         (*interface->output)(interface,egate,interface->hwaddr,AIP_TYPE,bp);
  167.     }
  168. }
  169.  
  170. /* Send a packet with Ethernet header */
  171. at_output(interface,dest,source,type,bp)
  172. struct interface *interface;        /* Pointer to interface control block */
  173. char dest[];        /* Destination Ethernet address */
  174. char source[];        /* Source Appletalk address */
  175. int16 type;        /* Type field */
  176. struct mbuf *bp;    /* Data field */
  177. {
  178.     struct    appletalk ap;    /* AppleTalk struct for header info. */
  179.     struct    mbuf    *hdr;
  180.     struct    mbuf    *htonat();
  181.  
  182.     memcpy(&ap.source, source, APPLE_LEN);
  183.     memcpy(&ap.dest, dest, APPLE_LEN);
  184.     ap.type = type;
  185.     hdr = htonat(&ap);
  186.     hdr->next = bp;
  187.     (*interface->raw)(interface,hdr);
  188. }
  189.  
  190. /* Send raw packet (caller provides header) */
  191. at_raw(interface,bp)
  192. struct interface *interface;        /* Pointer to interface control block */
  193. struct mbuf *bp;    /* Data field */
  194. {
  195.     register struct at *atp;    /* AppleTalk pointer */
  196.     short size;                    /* size of data in mbuf */
  197.     int err;                    /* error indicator from mac stuff */
  198.     short    tmp=2;                /* there is an offset of 2 in the data buffer */
  199.     short *mptr;                /* temporary pointer */
  200.     ABRecPtr abrwrptr;            /* pointer to applebuss record */
  201.     struct appletalk ap;        /* appletalk struct for front of record */
  202.     struct mbuf    *hdr;            /* extra mbuf pointer */
  203.     
  204.     atp = &at[interface->dev];
  205.     if ( interface->dev >= nat )
  206.     {
  207.         printf("problem with dev entry.  Number is  %d, max = %d\n", interface->dev,nat);
  208.         return(-1);
  209.     }
  210.     dump(interface,IF_TRACE_OUT,TRACE_APPLETALK,bp);
  211.     size = len_mbuf(bp);
  212.     
  213.     /*
  214.      * Set up the transmit structure
  215.      * take a part to get the address
  216.      */
  217.     ntohat(&ap, &bp);
  218.     abrwrptr = *atp->wrATptr;
  219.     abrwrptr->lapProto.lapAddress.dstNodeID = ap.dest;
  220.     abrwrptr->lapProto.lapDataPtr = atp->buffer;
  221.     abrwrptr->lapProto.lapAddress.lapProtType = atp->ProtoType;
  222.     
  223.     /*
  224.      * now put header back on
  225.      */
  226.      
  227.     hdr = htonat(&ap);
  228.     hdr->next = bp;
  229.  
  230.     /*
  231.         Copy all the data from the mbuf to the data packet holder.
  232.         Max amount of data is 600 bytes
  233.      */
  234.     while  ( hdr != NULLBUF)
  235.     {
  236.         bcopy(hdr->data, &abrwrptr->lapProto.lapDataPtr[tmp], hdr->cnt);
  237.         tmp += hdr->cnt;
  238.         if ( tmp >= 600)
  239.             printf("sending: ERROR IN PACKET SIZE, size = %d\n", tmp);
  240.  
  241.         hdr = free_mbuf(hdr);
  242.     }
  243.  
  244.     /* 
  245.         set the packet length in the first two bytes of the LAP data buffer
  246.         including these two bytes.
  247.      */
  248.      
  249.     mptr = (short *) abrwrptr->lapProto.lapDataPtr;
  250.     *mptr = tmp;
  251.     abrwrptr->lapProto.lapReqCount = tmp;
  252.     
  253.     atp->astats.out++;
  254.     
  255.     /* send off a sync write and wait for return value. */
  256.     
  257.     err = LAPWrite(atp->wrATptr, FALSE);
  258.     
  259.     if ( err != noErr )
  260.     {
  261.         printf("at_raw: write failure to AppleTalk (%d)\n", err);
  262.         return(0);
  263.     }
  264. }
  265.  
  266. /* Process any incoming AppleTalk packets on the receive queue */
  267. void
  268. at_recv(interface)
  269. struct interface *interface;
  270. {
  271.     struct at *atp;            /* appletalk pointer */
  272.     struct mbuf *bp;        /* place to store all the buffers */
  273.     ABRecPtr abrrdptr;        /* Appletalk network storage */
  274.     int    err;
  275.     extern int32 ip_addr;
  276.     struct appletalk ap;
  277.     struct mbuf *htonat();
  278.     
  279.     /*
  280.      *  just to make sure it is for us
  281.      */
  282.  
  283.     atp = &at[interface->dev];
  284.     
  285.     if ( interface->dev >= nat )
  286.     {
  287.         printf("problem with dev entry.  Number is  %d, max = %d\n", interface->dev,nat);
  288.         return;
  289.     }
  290.     
  291.     /*
  292.      * get a pointer to the read structure
  293.      */
  294.     
  295.     abrrdptr = *atp->rdATptr;
  296.     
  297.     /*
  298.      * since this was an async read, a 1 indicates it has not completed yet.
  299.      */
  300.  
  301.     if ( abrrdptr->lapProto.abResult == 1)
  302.     {
  303.         return;
  304.     }
  305.     else if  ( abrrdptr->lapProto.abResult == buf2SmallErr)
  306.     {
  307.         atp->astats.badsize++;
  308.         if ( at_startread(atp, abrrdptr ) != 0)
  309.         {
  310.             printf("Error in starting async read on Appletalk network.\n");
  311.         }
  312.         return;
  313.     }
  314.     else if  ( abrrdptr->lapProto.abResult == readQErr)
  315.     {
  316.         atp->astats.drop++;
  317.         if ( at_startread(atp, abrrdptr ) != 0)
  318.         {
  319.             printf("Error in starting async read on Appletalk network.\n");
  320.         }
  321.         return;
  322.     }
  323.     
  324.     /*
  325.      * now set up the mbuf. count -2 because AT puts in the count sent in the first two]
  326.      * bytes of the data.
  327.      */
  328.     
  329.     if((bp = alloc_mbuf(abrrdptr->lapProto.lapActCount-2)) == NULLBUF)
  330.     {
  331.         atp->astats.nomem++;
  332.         if ( at_startread(atp, abrrdptr ) != 0)
  333.         {
  334.             printf("Error in starting async read on Appletalk network.\n");
  335.         }
  336.         return;
  337.     }
  338.     
  339.     /*
  340.      * move it over
  341.      */
  342.  
  343.     bcopy(&abrrdptr->lapProto.lapDataPtr[2], bp->data, abrrdptr->lapProto.lapActCount-2);
  344.     
  345.     bp->cnt = abrrdptr->lapProto.lapActCount - 2;
  346.     
  347.     dump(interface,IF_TRACE_IN,TRACE_APPLETALK,bp);
  348.     
  349.     /* now start another async read on this device. */
  350.         
  351.     if ( at_startread(at, abrrdptr) != 0 )
  352.     {
  353.         printf("Could not perform read on AppleTalk network.  Closing down device.\n");
  354.         return;
  355.     }
  356.     ntohat(&ap, &bp);
  357.     
  358.     switch (ap.type)
  359.     {
  360.     
  361.         case AARP_TYPE:
  362.             arp_input(interface, bp);
  363.              atp->astats.any++;
  364.             break;
  365.         
  366.         case AIP_TYPE:
  367.             ip_route(bp, 0);
  368.              atp->astats.any++;
  369.             break;
  370.             
  371.         default:
  372.         /*
  373.             printf("at_recv: wrong type (%x)\n", ap.type);
  374.          */
  375.              atp->astats.badtype++;
  376.  
  377.              free_p(bp);
  378.             break;
  379.     }
  380. }
  381. /* Shut down the Appletalk controller */
  382. at_stop(interface)
  383. struct interface *interface;
  384. {
  385.     int16 dev;
  386.     struct at *atp;
  387.  
  388. #ifdef DEBUG
  389.     printf("at_stop called. dev = %d\n", interface->dev);
  390. #endif
  391.  
  392.     dev = interface->dev;
  393.     if ( dev >= nat)
  394.         return(-1);
  395.     atp = &at[dev];
  396.     
  397.     /* need to unlock the frozen pointers and cancel any reads outstanding */
  398.  
  399.     (void)HUnlock(atp->rdATptr);
  400.     (void)HUnlock(atp->wrATptr);
  401.     (void)LAPRdCancel(atp->rdATptr);
  402.  
  403.     /* make sure to close the procotol down and dispose or any pointers */
  404.     
  405.     (void)LAPCloseProtocol(atp->ProtoType);
  406.     (void)DisposHandle(atp->rdATptr);
  407.     (void)DisposHandle(atp->wrATptr);
  408.  
  409.     return(0);
  410. }
  411. /* Attach AppleTalk to the system
  412.  * argv[0]: hardware type, must be "appletalk"
  413.  * argv[1]: Protocol Type, e.g., "77"
  414.  * argv[2]: device name,must be "B"
  415.  * argv[3]: mode, must be "arpa"
  416.  * argv[4]: interface label, e.g., "at0"
  417.  * argv[5]: maximum number of packets allowed on receive queue, e.g., "5"
  418.  * argv[6]: maximum transmission unit, bytes, e.g., "600" < appletalk limitation.
  419.  */
  420. at_attach(argc,argv)
  421. int argc;
  422. char *argv[];
  423. {
  424.     register struct interface *if_at;
  425.     extern struct interface *ifaces;
  426.     unsigned dev;
  427.     char *calloc(),*malloc();
  428.     int at_init();
  429.     int at_send();
  430.     void at_recv();
  431.     int at_stop();
  432.     int err;
  433.     int pat(),gat();
  434.  
  435.     if(nat >= AT_MAX){
  436.         printf("at_attach: Too many AppleTalk interfaces.\r\n");
  437.         return(-1);
  438.     }
  439.     dev = nat++;
  440.     if_at = (struct interface *)calloc(1,sizeof(struct interface));
  441.  
  442.     if_at->name = malloc((unsigned)strlen(argv[4])+1);
  443.     strcpy(if_at->name,argv[4]);
  444.     if_at->mtu = atoi(argv[6]);
  445.     if_at->send = at_send;
  446.     if_at->output = at_output;
  447.     if_at->raw = at_raw;
  448.     if_at->recv = at_recv;
  449.     if_at->stop = at_stop;
  450.     if_at->dev = dev;
  451.     if_at->flags = 0;
  452.     at[dev].ProtoType = htoi(argv[1]);
  453.     at[dev].net = malloc(strlen(argv[2])+1);
  454.     strcpy(at[dev].net, argv[2]);
  455.  
  456.     if(strcmp(argv[3],"arpa") != 0){
  457.         printf("at_attach: Mode %s unknown for interface %s\n",
  458.             argv[3],argv[4]);
  459.         free((char *)if_at);
  460.         return -1;
  461.     }
  462.     arp_init(ARP_APPLETALK,APPLE_LEN,AIP_TYPE,AARP_TYPE,
  463.                 appletalk_bdcst,pat,gat);
  464.     if_at->next = ifaces;
  465.     ifaces = if_at;
  466.     /* Initialize device */
  467.     if ( (err = at_init(if_at,(unsigned)atoi(argv[5]))) != 0 )
  468.     {
  469.         printf("at_init: failed.\n");
  470.         exit(-1);
  471.     }
  472.     else
  473.     {
  474.         return 0;
  475.     }
  476. }
  477.  
  478. /*
  479.     this procedure will start up an async read on the appletalk network
  480.  */
  481.  
  482. at_startread(atp, readptr)
  483. struct at *atp;
  484. ABRecPtr readptr;
  485. {
  486.     int err;
  487.     
  488.     /*
  489.      * set up the structure for a read
  490.      */
  491.      
  492.     readptr->lapProto.lapAddress.lapProtType = atp->ProtoType;
  493.     readptr->lapProto.lapReqCount = MAX_ATBUF;
  494.     readptr->lapProto.lapDataPtr = atp->buffer;
  495.     
  496.     /*
  497.      * issue the read using the async flag
  498.      */
  499.  
  500.     err = LAPRead( atp->rdATptr, TRUE);
  501.     if ( err != noErr )
  502.     {
  503.         (void)LAPRdCancel(atp->ProtoType);
  504.         (void)LAPCloseProtocol(atp->ProtoType);
  505.         (void)DisposHandle(atp->rdATptr);
  506.         (void)DisposHandle(atp->wrATptr);
  507.         return(-1);
  508.     }            
  509.     return(0);
  510. }
  511.  
  512. bcopy(from, to, cnt)
  513. char *to, *from;
  514. int cnt;
  515. {
  516.     while ( cnt-- != 0 )
  517.     {
  518.         *to++ = *from++;
  519.     }
  520. }
  521. /* Format an AppleTalk address into a printable ascii string */
  522. pat(out,addr)
  523. char *out,*addr;
  524. {
  525.     sprintf(out,"%02x", *addr & 0xff);
  526. }
  527.  
  528. /* Convert an AppleTalk address from Hex/ASCII to binary */
  529. gat(out,cp)
  530. register char *out;
  531. register char *cp;
  532. {
  533.     register int i;
  534.  
  535.     *out = htoi(cp);
  536. }
  537.  
  538. /* Convert AppleTalk header in host form to network mbuf */
  539. struct mbuf *
  540. htonat(ap)
  541. struct appletalk *ap;
  542. {
  543.     struct mbuf *bp;
  544.     register char *cp;
  545.     bp = alloc_mbuf(APPLEADDRLEN);
  546.     bp->cnt = APPLEADDRLEN;
  547.     cp = bp->data;
  548.     memcpy(cp,&ap->dest,APPLE_LEN);
  549.     cp += APPLE_LEN;
  550.     memcpy(cp,&ap->source,APPLE_LEN);
  551.     cp += APPLE_LEN;
  552.     put16(cp,ap->type);
  553.  
  554.     return bp;
  555. }
  556. /* Extract AppleTalk header */
  557. ntohat(ap,bpp)
  558. struct appletalk *ap;
  559. struct mbuf **bpp;
  560. {
  561.     pullup(bpp,&ap->dest,APPLE_LEN);
  562.     pullup(bpp,&ap->source,APPLE_LEN);
  563.     ap->type = pull16(bpp);
  564.     return APPLEADDRLEN;
  565. }
  566.  
  567.  
  568.  
  569. int
  570. doatstat(argc,argv)
  571. int argc;
  572. char *argv[];
  573. {
  574.     struct at *atp;
  575.  
  576.     for(atp = at;atp < &at[nat]; atp++){
  577.         
  578.         printf("Controller %u:\n",atp-at);
  579.  
  580.         printf("any      output    badtype   nomem     drop     badsize\n");
  581.         printf("%-10lu%-10lu%-10lu%-10lu%-10lu%-10lu\n",
  582.          atp->astats.any, atp->astats.out,
  583.          atp->astats.badtype, atp->astats.nomem,
  584.          atp->astats.drop, atp->astats.badsize);
  585.     }
  586.     return 0;
  587. }
  588.  
  589. mac_netevt(msg)
  590. ABRecHandle msg;
  591. {
  592. }
  593.